/**
 * 
 */
package com.primestone.cim.meterreadings;

import java.util.List;
import java.util.Scanner;

import javax.xml.ws.Holder;

import ch.iec.tc57._2011.getmeterreadingsmessage.GetMeterReadingsRequestType;
import ch.iec.tc57._2011.meterreadings.FaultMessage;
import ch.iec.tc57._2011.schema.message.HeaderType;
import ch.iec.tc57._2011.schema.message.MessageProperty;
import ch.iec.tc57._2011.schema.message.OptionType;

import com.primestone.cim.util.CollectionUtil;
import com.primestone.cim.util.StringUtil;
import com.primestone.cim.util.enums.RegexEnum;
import com.primestone.cim.util.enums.SocDevEnum;


/**
 * @author cesar.mateus
 * Nov 14, 2013 11:42:13 AM
 * Extractor.java
 * GetMeterReadings
 * 
 */
public class Extractor {
		
	/**
	 * 
	 * @param request
	 * @return
	 */
	public static Integer extractTop(GetMeterReadingsRequestType request) {
		String extractedOption = extractOption(request, StringUtil.TOP_NAME);
		if (RegexEnum.ONLY_DIGITS.getPattern().matcher(extractedOption).matches()) {
			return Integer.valueOf(extractedOption);
		}
		return null;
	}
	
	/**
	 * El id de bloque que este metodo extrae corresponde a un id de bloque a eliminar enviado por el sistema cliente; 
	 * a partir del cual se buscara un siguiente bloque a enviar. <BR/>
	 * No es un parametro obligatorio, pero el manejo de su secuencia debe ser muy cuidadoso por parte del sistema cliente. 
	 * @param request Parametro que contiene una peticion del sistema cliente.
	 * @return El valor del parametro {@link com.primestone.cim.util.StringUtil#OLD_BLOCK_NAME}.
	 * @throws FaultMessage 
	 */
	public static Long extractOldBlock(GetMeterReadingsRequestType request) {
		String extractedOption = extractOption(request, StringUtil.OLD_BLOCK_NAME);
		if (StringUtil.safe(extractedOption)) {
			Scanner scanner = new Scanner(extractedOption);
			boolean hasNextLong = scanner.hasNextLong();
			if (hasNextLong) {
				return scanner.nextLong();
			}	
		}
		return null;
	}
	
	/**
	 * 
	 * @param request
	 * @return
	 */
	public static String extractSocketDeviceFlag(GetMeterReadingsRequestType request) {
		if (StringUtil.safe(extractSocket(request))) {
			return SocDevEnum.WORK_SOCKETS.getCode();
		} else if (StringUtil.safe(extractDevice(request))) {
			return SocDevEnum.WORK_DEVICES.getCode();
		}
		return null;
	}
	
	/**
	 * 
	 * @param request
	 * @return
	 */
	public static String extractSocket(GetMeterReadingsRequestType request) {
		return extractOption(request, StringUtil.SOCKET_FIELD_NAME);
	}
	
	/**
	 * 
	 * @param request
	 * @return
	 */
	public static String extractVarType(GetMeterReadingsRequestType request) {
		return extractOption(request, StringUtil.VARTYPE_FIELD_NAME);
	}
	
	
	/**
	 * 
	 * @param request
	 * @return
	 */
	public static String extractDevice(GetMeterReadingsRequestType request) {
		return extractOption(request, StringUtil.DEVICE_FIELD_NAME);
	}
	
	/**
	 * 
	 * @param request
	 * @return
	 */
	public static boolean extractOnlyNewParameter(GetMeterReadingsRequestType request) {
		String extractedOption = extractOption(request, StringUtil.ONLY_NEW_READINGS);
		if (StringUtil.safe(extractedOption)) {
			return true;
		}
		return false;
	}
	
	/**
	 * @param request
	 * @return
	 */
	public static boolean extractBatchParameter(GetMeterReadingsRequestType request) {
		String extractedOption = extractOption(request, StringUtil.BATCH_NAME);
		if (StringUtil.safe(extractedOption)) {
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @param header
	 * @return
	 */
	public static String extractTicket(Holder<HeaderType> header) {
		if (header.value != null) {
			List<MessageProperty> properties = header.value.getProperty();
			for (MessageProperty messageProperty : properties) {
				if(messageProperty.getName().equals(StringUtil.TICKET_FIELD_NAME)) {
					return messageProperty.getValue();
				}
			}
		}
		return null;
	}

	/**
	 * 
	 * @param header
	 * @param ticket
	 */
	public static void putTicket(Holder<HeaderType> header, String ticket) {
		if (header.value != null) {			
			MessageProperty messageProperty = new MessageProperty();
			messageProperty.setName(StringUtil.TICKET_FIELD_NAME);
			messageProperty.setValue(ticket);
			header.value.getProperty().add(messageProperty);			
		}
	}

	/**
	 * 
	 * @param properties
	 * @return
	 */
	public static String extractPwd(List<MessageProperty> properties) {
		if (CollectionUtil.safe(properties)) {
			for (MessageProperty messageProperty : properties) {
				if (StringUtil.safe(messageProperty.getName()) && StringUtil.safe(messageProperty.getValue()) 
						&& messageProperty.getName().equals(StringUtil.PWD_PROP_NAME) ) {
					return messageProperty.getValue();
				}
			}	
		}
		
		return null;
	}

	/**
	 * 
	 * @param request
	 * @param optionName
	 * @return
	 */
	private static String extractOption(GetMeterReadingsRequestType request, String optionName) {
		if (request != null) {
			List<OptionType> options = request.getOption();
			if (CollectionUtil.safe(options)) {
				for (OptionType option : options) {
					if (option.getName().equals(optionName)) {
						return option.getValue();
					}	
				}	
			}	
		}
		return null;
	}

}
